--Matt Forbes
--body file
--package for handling long ints
--11/6/2009

with ada.text_io;
with ada.characters.handling;

package body long_int_handling is

    package t_io renames ada.text_io;
    package c_h renames ada.characters.handling;

    procedure add_long_ints(num_1 : in_string; size1 : Integer; num_2 : in_string; size2 : Integer) is
	out_num : out_string;
	int1, int2, num_to_add : Integer;
	difference : Integer;
	carry_one : Boolean;
    begin
	carry_one := FALSE;
	for i in reverse max_output loop
	    if i > 1 then
		int1 := character'pos(num_1(i-1)) - character'pos('0');
		int2 := character'pos(num_2(i-1)) - character'pos('0');
		num_to_add := int1 + int2;
	    else
		num_to_add := 0;
	    end if;
	    if carry_one then
		num_to_add := num_to_add +1;
	    end if;
	    if num_to_add >= 10 then
		carry_one := TRUE;
		num_to_add := num_to_add - 10;
	    else
		carry_one := FALSE;
	    end if;
	    out_num(i) := character'val(num_to_add + character'pos('0'));
	end loop;

	if size1 < size2 then
	    difference := size2 - size1;
	    for i in 0..difference loop
		t_io.put(" ");
	    end loop;
	    read_long_int(num1);
	    t_io.new_line;
	    read_long_int(num2);
	    for i in 0..difference loop
		t_io.put("-");
	    end loop;
	    read_long_int_output(sum);
	else
	    difference := size1 - size2;
	    read_long_int(num1);
	    for i in 0..difference loop
		t_io.put(" ");
	    end loop;
	    read_long_int(num2);
	    for i in 0..difference loop
		t_io.put("-");
	    end loop;
	    read_long_int_output(sum);
	end if;


    end add_long_ints;

    function get_long_int return in_string is
	ret_string, tmp : in_string;
	cur_char : Character;
	len, index, filler : Integer;
    begin
	len := 1;
	index := 1;

	while index <= in_string'last loop
	    ret_string(index) := '0';
	    tmp(index) := '0';
	    index := index + 1;
	end loop;

	index := 1;

	t_io.put("Enter a number (max ");
	t_io.put(Integer'Image(in_string'last));
	t_io.put(" digits)  > ");
	begin
	    loop
		t_io.get(Item => cur_char);
		if c_h.is_digit(cur_char) then
		    tmp(index) := cur_char;
		    len := len + 1;
		    index := index + 1;
		end if;
		exit when t_io.end_of_line;
	    end loop;
	exception
	    when constraint_error =>
		t_io.skip_line;
		t_io.put("Input too long, truncated to ");
		t_io.put(Item => tmp);
		t_io.put_line(".");
	end;

	filler := in_string'last - len ;
	index := filler + 2;
	
	while index <= in_string'last loop
	    ret_string(index) := tmp(len - (in_string'last - index) - 1);
	    index := index + 1;
	end loop;
    
	return ret_string;
    end get_long_int;

    procedure read_long_int_output(out_num : in out_string) is
	reading : Boolean;
    begin
	reading := FALSE;
	for i in max_output loop
	    if reading then
		t_io.put(out_num(i));
	    elsif out_num(i) /= '0' then
		reading := TRUE;
		t_io.put(out_num(i));
	    end if;
	end loop;
	if reading = FALSE then
	    t_io.put('0');
	end if;
    end read_long_int_output;

    procedure read_long_int(out_num : in in_string) is
	reading : Boolean;
    begin
	reading := FALSE;
	for i in max_input loop
	    if reading then
		t_io.put(out_num(i));
	    elsif out_num(i) /= '0' then
		reading := TRUE;
		t_io.put(out_num(i));
	    end if;
	end loop;
	if reading = FALSE then
	    t_io.put('0');
	end if;
    end read_long_int;


end long_int_handling;
